package plgbase

import (
	"fmt"
	"gitee.com/ymofen/gobase"
	"gitee.com/ymofen/gobase/evthub"
	"gitee.com/ymofen/supervalue"
)

type EvtCall struct {
	evtNode *evthub.EvtNode
	evtid   string

	OnClose         func()
	OnConfigChanged func(confMap gobase.StrMap, raw string)
	confstr         string
}

const (
	EVT_ACTION_CLOSE = 9

	// action, confMap, raw
	EVT_ACTION_RELOAD = 1
)

func (this *EvtCall) closeEvt() {
	if this.evtNode != nil {
		fn := this.OnClose
		if fn != nil {
			fn()
		}
		evthub.DefaultEvtHub.ReleasesEvtNode(this.evtid)
		this.evtNode = nil
	}
}

func NewEvtCall() *EvtCall {
	rval := &EvtCall{}
	return rval
}

func (this *EvtCall) Close() error {
	this.closeEvt()
	return nil
}

func (this *EvtCall) Valid() bool {
	return this.evtNode != nil
}

func (this *EvtCall) Status() string {
	if this.evtNode == nil {
		return fmt.Sprintf("%s(NIL)", this.evtid)
	} else {
		return fmt.Sprintf("%s-%p", this.evtid, this.evtNode)
	}
}

// 如果evtid改变, 则会关闭之前的
// 检测EvtNode是否存在
// 可以重复调用, 插件关闭时需要调用Clsoe()
func (this *EvtCall) CheckEvent(conf *wrapper.SuperValue) error {
	if conf == nil {
		this.closeEvt()
		return nil
	}

	s := conf.String()
	if this.confstr != s {
		this.confstr = s
		confMap := gobase.NewStrMap()
		wrapper.SV2StrMap(confMap, conf)
		var evtid string
		if len(confMap) == 0 {
			evtid = s
		} else {
			evtid = confMap.StringByName("id", "")
		}

		if evtid != this.evtid {
			this.closeEvt()
			this.evtid = evtid
			if len(this.evtid) > 0 {
				this.evtNode = evthub.DefaultEvtHub.CheckGetEvtNode(this.evtid, true)
			}
		}
		if this.evtNode != nil {
			fn := this.OnConfigChanged
			if fn != nil {
				fn(confMap, s)
			}
		}
	}
	return nil
}

func (this *EvtCall) ExecuteEvt(max int, args ...interface{}) (cnt int) {
	evtNode := this.evtNode
	if evtNode == nil {
		return -1
	}
	return evtNode.Execute(max, args...)
}
